<template>
  <div>
    <div id="cesiumContainer"></div>
    <div
      style="
        position: fixed;
        width: 100px;
        height: 30px;
        z-index: 9;
        margin-left: 180px;
      "
    >
      <!-- <button id="huizhi" @click="huizhiyanmo">淹没分析</button> -->
      <button @click="clearAllEntities">清除淹没分析</button>
    </div>
    <div
      style="
        position: fixed;
        width: 100px;
        height: 30px;
        z-index: 9;
        margin-left: 280px;
      "
    >
      <input type="range" v-model="value" />
      <button @click="shuiweiup">开始升降</button>
    </div>

    <!-- <div id="toolbar">
      <button id="startFlow">开始水流</button>
      <button id="stopFlow">停止水流</button>
      <button id="increaseFlow">增加流量</button>
      <button id="decreaseFlow">减少流量</button>
    </div> -->
    <!-- <div id="controlPanel">
      <div class="control-group">
        <button id="initScene" @click="initializeScene">初始化场景</button>
      </div>
      <div class="control-group">
        <label>闸门开度 (%)</label>
        <div class="slider-container">
          <input type="range" id="gateOpenness" min="0" max="100" value="0" />
          <span class="slider-value" id="gateOpennessValue">0</span>
        </div>
        <button id="autoOpenGate">自动开启闸门</button>
      </div>
      <div class="control-group">
        <label>水流速度</label>
        <div class="slider-container">
          <input type="range" id="flowSpeed" min="1" max="10" value="3" />
          <span class="slider-value" id="flowSpeedValue">3</span>
        </div>
      </div>
      <div class="control-group">
        <label>水流流量</label>
        <div class="slider-container">
          <input type="range" id="flowRate" min="10" max="200" value="50" />
          <span class="slider-value" id="flowRateValue">50</span>
        </div>
      </div>
      <div class="control-group">
        <button id="resetSimulation">重置模拟</button>
      </div> -->
    <!-- </div> -->
  </div>
  <!-- <HomeViewVue /> -->
</template>


<script>
// import Line from "./views/line.json";
import Line from "./line2.json";
import HomeViewVue from "./views/HomeView.vue";
export default {
  data() {
    return {
      value: 70,
      activeShapePoints: "",
      floatingPoint: "",
      activeShape: "",
      handler: "",
      maxWaterHeight: "",
      minWaterHeight: "",
      waterHeight: "",
      tempEntities: "",
      undefinedisDraw: "",
      isDraw: false,
      polylinedata: "",
      viewer: null,
      entity: null,
      startMousePosition: null,
      currentMousePosition: null,
      position: {
        longitude: 116.39,
        latitude: 39.9,
        height: 0,
      },
      orientation: {
        heading: 0,
        pitch: 0,
        roll: 0,
      },

      //   isDraw: false,
      //  maxWaterHeight: 2000,
      minWaterHeight: 0,
      warningWaterHeight: 0, // 预警高度
      waterHeight: 0,
      waterHeightShow: false,
      speed: "1",
      waterHeightTimeer: 0,
      waterPrimitive: undefined,
      // tempEntities: [],
      viewModel: {
        emissionRate: 1,
        gravity: 0.0, //设置重力参数
        minimumParticleLife: 1,
        maximumParticleLife: 2,
        minimumSpeed: 0.00002, //粒子发射的最小速度
        maximumSpeed: 0.00006, //粒子发射的最大速度
        speed: 0.3,
        startScale: 30,
        endScale: 50,
        particleSize: 2,
      },
      emitterModelMatrix: null,
      translation: null,
      rotation: null,
      hpr: null,
      trs: null,
      scene: null,
      //   particleSystem: "",
      aper: "",
      primitive: "",
      //  entity: null,
      textureCoordinates: "",
      newData: "",

      // 开闸放水参数
      reservoir: "", // 水库水体实体
      spillwayTileset: "", // 泄洪道3DTiles模型
      gateEntities: [], // 闸门实体
      particleSystem: "", // 水流粒子系统
      animationInterval: "", // 动画间隔
      waterLevel: 100, // 初始水位高度(米)
      isGateOpening: false, // 闸门是否正在开启
      currentGateOpenness: 0, // 当前闸门开度(0-100)

      // 模拟参数
      simulationParams: {
        flowSpeed: 3,
        flowRate: 50,
        waterDecreaseRate: 0.05,
      },
    };
  },
  components: {
    HomeViewVue,
  },
  mounted() {
    this.init2();
    setTimeout(() => {
      this.huizhiyanmo();
    }, 3000);
  },
  methods: {
    init2() {
      Cesium.Ion.defaultAccessToken =
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjMDNlOGNlOC1lMzlmLTQ1MzktYjE1ZC1iYzAzYjQyNGY1NjciLCJpZCI6MjQ3ODgzLCJpYXQiOjE3Mjg4NzQ1MDd9.bgtSMHuni0Mn1M2-WZAg9Ip5F-SSKJKP7pFbyGBvCj4";
      const viewer = new Cesium.Viewer("cesiumContainer", {
        // terrainProvider: Cesium.createWorldTerrain({
        //   url: "https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles",
        //   requestVertexNormals: true,
        //   requestWaterMask: true, // 展示地形和水体遮罩
        // }),
        requestRenderMode: true, // 按需渲染
        scene3DOnly: true, // 纯3D模式
        shadows: false, // 关闭阴影
        fxaa: false, // 关闭抗锯齿
        shouldAnimate: true, // 关闭自动动画
        msaaSamples: 4, // 中端设备用4x
        useBrowserRecommendedResolution: false, // 禁用自动分辨率
        targetFrameRate: 60, // 目标帧率
      });
      // 使用低分辨率或简化版底图
      viewer.imageryProvider = new Cesium.ArcGisMapServerImageryProvider({
        url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
      });
      ///   使用简化地形或关闭地形
      viewer.terrainProvider = Cesium.createWorldTerrain({
        requestWaterMask: false, // 关闭水面效果
        requestVertexNormals: false, // 关闭顶点法线
      });
      // 减少最大可视距离
      // viewer.scene.screenSpaceCameraController.maximumZoomDistance = 10000000;
      // 降低地形细节
      viewer.scene.terrainExaggeration = 1.0;
      // 启用预加载
      viewer.scene.preloadFlightDestinations = true;
      viewer.scene.preloadAnimatedCameraPosition = true;
      // 只加载可视范围内的数据
      viewer.scene.globe.tileCacheSize = 1000;
      viewer.scene.fog.enabled = false;
      this.viewer = viewer;
      // 去除logo
      viewer.cesiumWidget.creditContainer.style.display = "none";
      // 显示帧率
      viewer.scene.debugShowFramesPerSecond = true;
      viewer.scene.globe.depthTestAgainstTerrain = true;

      // 调试使用
      window.viewer = viewer;

      let translation = Cesium.Cartesian3.fromArray([0, 0, 0]);
      let m = Cesium.Matrix4.fromTranslation(translation);

      this.emitterModelMatrix = new Cesium.Matrix4();
      this.translation = new Cesium.Cartesian3();
      this.rotation = new Cesium.Quaternion();
      this.hpr = new Cesium.HeadingPitchRoll();
      this.trs = new Cesium.TranslationRotationScale();
      this.scene = viewer.scene;
      this.particleSystem = "";
      this.entity = viewer.entities.add({
        //选择粒子放置的坐标 经度：112.73959663183864, 纬度：31.135803413150533
        position: Cesium.Cartesian3.fromDegrees(
          112.73959663183864,
          31.135803413150533,
          100
        ),
        // hierarchy: activeShapePoints,
        // orientation: Cesium.Quaternion.fromHeadingPitchRoll(
        //   new Cesium.HeadingPitchRoll(
        //     Cesium.Math.toRadians(-30),
        //     Cesium.Math.toRadians(-50),
        //     Cesium.Math.toRadians(-10)
        //   )
        // ),
        //  Cesium.Quaternion.fromRotationMatrix(
        //   Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(330))
        // ),
      });
      let modelarr = [
        "http://192.168.10.80:9099/3dtiles1/tileset.json",
        "http://192.168.10.80:9099/3dtiles2/tileset.json",
        "http://192.168.10.80:9099/3dtiles3/tileset.json",
      ];
      // const url = "http://192.168.10.80:9099/3dtiles1/tileset.json";
      // const url = "http://192.168.10.80:9099/3dtiles2/tileset.json";
      // const url = "http://192.168.10.80:9099/3dtiles3/tileset.json";
      modelarr.forEach((url) => {
        let tilesetJson = {
          url,
          modelMatrix: m,
          show: true, // 是否显示图块集(默认true)
          skipLevelOfDetail: true, // --- 优化选项。确定是否应在遍历期间应用详细级别跳过(默认false)
          baseScreenSpaceError: 1024, // --- When skipLevelOfDetailis true，在跳过详细级别之前必须达到的屏幕空间错误(默认1024)
          maximumScreenSpaceError: 32, // 数值加大，能让最终成像变模糊---用于驱动细节细化级别的最大屏幕空间误差(默认16)原128
          skipScreenSpaceErrorFactor: 16, // --- 何时skipLevelOfDetail是true，定义要跳过的最小屏幕空间错误的乘数。与 一起使用skipLevels来确定要加载哪些图块(默认16)
          skipLevels: 1, // --- WhenskipLevelOfDetail是true一个常量，定义了加载图块时要跳过的最小级别数。为 0 时，不跳过任何级别。与 一起使用skipScreenSpaceErrorFactor来确定要加载哪些图块。(默认1)
          immediatelyLoadDesiredLevelOfDetail: false, // --- 当skipLevelOfDetail是时true，只会下载满足最大屏幕空间错误的图块。忽略跳过因素，只加载所需的图块(默认false)
          loadSiblings: false, // 如果为true则不会在已加载完概况房屋后，自动从中心开始超清化房屋 --- 何时确定在遍历期间skipLevelOfDetail是否true始终下载可见瓦片的兄弟姐妹(默认false)
          cullWithChildrenBounds: false, // ---优化选项。是否使用子边界体积的并集来剔除瓦片（默认true）
          cullRequestsWhileMoving: false, // ---优化选项。不要请求由于相机移动而在返回时可能未使用的图块。这种优化只适用于静止的瓦片集(默认true)
          cullRequestsWhileMovingMultiplier: 10, // 值越小能够更快的剔除 ---优化选项。移动时用于剔除请求的乘数。较大的是更积极的剔除，较小的较不积极的剔除(默认60)原10
          preloadWhenHidden: true, // ---tileset.show时 预加载瓷砖false。加载图块，就好像图块集可见但不渲染它们(默认false)
          preloadFlightDestinations: true, // ---优化选项。在相机飞行时在相机的飞行目的地预加载图块(默认true)
          preferLeaves: true, // ---优化选项。最好先装载叶子(默认false)
          maximumMemoryUsage: 2048, // 内存分配变小有利于倾斜摄影数据回收，提升性能体验---瓦片集可以使用的最大内存量（以 MB 为单位）(默认512)原512 4096
          progressiveResolutionHeightFraction: 0.5, // 数值偏于0能够让初始加载变得模糊 --- 这有助于在继续加载全分辨率图块的同时快速放下图块层(默认0.3)
          dynamicScreenSpaceErrorDensity: 10, // 数值加大，能让周边加载变快 --- 用于调整动态屏幕空间误差的密度，类似于雾密度(默认0.00278)
          dynamicScreenSpaceErrorFactor: 1, // 不知道起了什么作用没，反正放着吧先 --- 用于增加计算的动态屏幕空间误差的因素(默认4.0)
          dynamicScreenSpaceErrorHeightFalloff: 0.25, // --- 密度开始下降的瓦片集高度的比率(默认0.25)
          foveatedScreenSpaceError: true, // --- 优化选项。通过暂时提高屏幕边缘周围图块的屏幕空间错误，优先加载屏幕中心的图块。一旦Cesium3DTileset#foveatedConeSize加载确定的屏幕中心的所有图块，屏幕空间错误就会恢复正常。(默认true)
          foveatedConeSize: 0.1, // --- 优化选项。当Cesium3DTileset#foveatedScreenSpaceError为 true 时使用来控制决定延迟哪些图块的锥体大小。立即加载此圆锥内的瓷砖。圆锥外的瓷砖可能会根据它们在圆锥外的距离及其屏幕空间误差而延迟。这是由Cesium3DTileset#foveatedInterpolationCallback和控制的Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation。将此设置为 0.0 意味着圆锥将是由相机位置及其视图方向形成的线。将此设置为 1.0 意味着锥体包含相机的整个视野,禁用效果(默认0.1)
          foveatedMinimumScreenSpaceErrorRelaxation: 0.0, // --- 优化选项。当Cesium3DTileset#foveatedScreenSpaceError为 true 时使用以控制中央凹锥之外的图块的起始屏幕空间误差松弛。屏幕空间错误将从 tileset 值开始Cesium3DTileset#maximumScreenSpaceError根据提供的Cesium3DTileset#foveatedInterpolationCallback.(默认0.0)
          // foveatedTimeDelay: 0.2, // ---优化选项。使用 whenCesium3DTileset#foveatedScreenSpaceError为 true 来控制在相机停止移动后延迟瓷砖开始加载之前等待的时间（以秒为单位）。此时间延迟可防止在相机移动时请求屏幕边缘周围的瓷砖。将此设置为 0.0 将立即请求任何给定视图中的所有图块。(默认0.2)
          luminanceAtZenith: 0.2, // --- 用于此模型的程序环境贴图的天顶处的太阳亮度（以千坎德拉每平方米为单位）(默认0.2)
          backFaceCulling: true, // --- 是否剔除背面几何体。当为 true 时，背面剔除由 glTF 材质的 doubleSided 属性确定；如果为 false，则禁用背面剔除(默认true)
          debugFreezeFrame: false, // --- 仅用于调试。确定是否应仅使用最后一帧的图块进行渲染(默认false)
          debugColorizeTiles: false, // --- 仅用于调试。如果为 true，则为每个图块分配随机颜色(默认false)
          debugWireframe: false, // --- 仅用于调试。如果为 true，则将每个图块的内容渲染为线框(默认false)
          debugShowBoundingVolume: false, // --- 仅用于调试。如果为 true，则为每个图块渲染边界体积(默认false)
          debugShowContentBoundingVolume: false, // --- 仅用于调试。如果为 true，则为每个图块的内容渲染边界体积(默认false)
          debugShowViewerRequestVolume: false, // --- 仅用于调试。如果为 true，则呈现每个图块的查看器请求量(默认false)
          debugShowGeometricError: false, // --- 仅用于调试。如果为 true，则绘制标签以指示每个图块的几何误差(默认false)
          debugShowRenderingStatistics: false, // --- 仅用于调试。如果为 true，则绘制标签以指示每个图块的命令、点、三角形和特征的数量(默认false)
          debugShowMemoryUsage: false, // --- 仅用于调试。如果为 true，则绘制标签以指示每个图块使用的纹理和几何内存（以兆字节为单位）(默认false)
          debugShowUrl: false, // --- 仅用于调试。如果为 true，则绘制标签以指示每个图块的 url(默认false)
          dynamicScreenSpaceError: true, // 根据测试，有了这个后，会在真正的全屏加载完之后才清晰化房屋 --- 优化选项。减少距离相机较远的图块的屏幕空间错误(默认false)
        };
        const tileset = new Cesium.Cesium3DTileset(tilesetJson);
        viewer.flyTo(tileset);
        // 异步加载
        tileset.readyPromise
          .then(function (tileset) {
            viewer.scene.primitives.add(tileset);
          })
          .catch(function (error) {
            console.log(error);
          });
        tileset.allTilesLoaded.addEventListener(function () {
          console.log("模型已经全部加载完成");
        });
      });
      //   添加一个红点
      // const pointPrimitive = viewer.scene.primitives.add(
      //   new Cesium.PointPrimitiveCollection({
      //     debugShowBoundingVolume: false,
      //   })
      // );

      // pointPrimitive.add({
      //   position: Cesium.Cartesian3.fromDegrees(
      //     112.74632167517368,
      //     31.134263048237873,
      //     100
      //   ),
      //   pixelSize: 12,
      //   color: Cesium.Color.RED,
      //   disableDepthTestDistance: Number.POSITIVE_INFINITY, // 禁用深度测试
      // });
      viewer.scene.globe.depthTestAgainstTerrain = false;
      // setTimeout(() => {
      // 加载 GLB 模型  经度：112.74614836770245, 纬度：31.134024851572637
      //经度：112.74598794382572, 纬度：31.13408755118914  经度：112.7475709439853, 纬度：31.134461793674227
      //经度：112.74628207351466, 纬度：31.13453829918629 经度：112.74601811262656, 纬度：31.134178781743067
      // 经度：112.74632167517368, 纬度：31.134263048237873
      const position = Cesium.Cartesian3.fromDegrees(
        112.74632167517368,
        31.134263048237873,
        0
      ); //

      // const position = Cartesian3.fromDegrees(116.39, 39.9, 0);
      const heading = Cesium.Math.toRadians(-110); // 45 度偏航
      const pitch = Cesium.Math.toRadians(-60); // 10 度俯仰
      const roll = Cesium.Math.toRadians(0); // 无翻滚

      // 方法 1：使用 Euler 角转 Quaternion
      const orientation = Cesium.Quaternion.fromHeadingPitchRoll(
        new Cesium.HeadingPitchRoll(heading, pitch, roll)
      );
      const modelEntity = viewer.entities.add({
        position: position,
        // orientation: {
        //   direction: new Cesium.Cartesian3(1, 0, 0), // 默认前进方向为 X 轴
        //   heading: Cesium.Math.toRadians(90), // 模型旋转 90 度（校正朝向）
        // },
        orientation: orientation, // 或 finalOrientation
        model: {
          uri: "./大坝.glb", // GLB 路径（需放在 public/models/ 下）
          // minimumPixelSize: 64, // 模型最小像素尺寸
          // maximumScale: 200, // 最大缩放比例
          allowPicking: true, // 确保模型可以被拾取
        },
      });
      // 启用拖拽和朝向获取
      // this.setupRotationBehavior();
      // 聚焦到模型
      // viewer.camera.flyTo({
      //   destination: Cesium.Cartesian3.fromDegrees(
      //     112.7460645937131,
      //     31.135216886898544,
      //     500
      //   ),
      //   // orientation: {
      //   //   heading: Cesium.Math.toRadians(0),
      //   //   pitch: Cesium.Math.toRadians(-30),
      //   // },
      // });

      // 拖拽和旋转控制
      let isDragging = false;
      let isRotating = false;
      let previousPosition = null;
      let startAngle = 0;
      let initialOrientation = null;

      let dragStartPosition = null;
      let dragStartModelPosition = null;

      // 初始化拖拽相关变量

      let startScreenPos = new Cesium.Cartesian2();
      let startWorldPos = new Cesium.Cartesian3();
      let initialModelMatrix = new Cesium.Matrix4();

      // 确保模型加载完成后初始化矩阵
      // viewer.scene.postRender.addEventListener(() => {
      //   if (modelEntity.model && !modelEntity.model.ready) return;

      //   if (!initialModelMatrix.equals(Cesium.Matrix4.IDENTITY)) return;

      //   // 获取初始模型矩阵
      //   initialModelMatrix = Cesium.Matrix4.clone(
      //     modelEntity.model.modelMatrix
      //   );
      //   console.log("模型矩阵初始化完成");
      // }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

      // 事件处理器
      // const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

      // // 鼠标按下：开始拖拽
      // handler.setInputAction((movement) => {
      //   const picked = viewer.scene.pick(movement.position);
      //   if (picked && picked.id === modelEntity) {
      //     isDragging = true;

      //     // 记录初始位置
      //     startScreenPos = Cesium.Cartesian2.clone(movement.position);
      //     startWorldPos = viewer.scene.pickPosition(movement.position);

      //     // 高亮模型（可选）
      //     modelEntity.model.color = Cesium.Color.YELLOW.withAlpha(0.6);
      //   }
      // }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

      // // 鼠标移动：计算位移
      // handler.setInputAction((movement) => {
      //   if (!isDragging) return;

      //   const endScreenPos = movement.endPosition;
      //   const endWorldPos = viewer.scene.pickPosition(endScreenPos);

      //   if (Cesium.defined(startWorldPos)) {
      //     // 计算世界坐标系中的位移向量
      //     const delta = Cesium.Cartesian3.subtract(
      //       endWorldPos,
      //       startWorldPos,
      //       new Cesium.Cartesian3()
      //     );

      //     // 应用平移变换
      //     const currentMatrix = modelEntity.model.modelMatrix;
      //     const translationMatrix = Cesium.Matrix4.fromTranslation(delta);
      //     const newMatrix = Cesium.Matrix4.multiply(
      //       currentMatrix,
      //       translationMatrix,
      //       new Cesium.Matrix4()
      //     );

      //     // 更新模型矩阵
      //     modelEntity.model.modelMatrix = newMatrix;

      //     // 更新起始点为当前位置
      //     startWorldPos = endWorldPos;
      //   }
      // }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

      // // 鼠标释放：结束拖拽
      // handler.setInputAction(() => {
      //   if (isDragging) {
      //     isDragging = false;
      //     modelEntity.model.color = Cesium.Color.WHITE; // 恢复颜色
      //   }
      // }, Cesium.ScreenSpaceEventType.LEFT_UP);
      // // 右键旋转
      // handler.setInputAction((movement) => {
      //   const pickedObject = viewer.scene.pick(movement.position);
      //   if (Cesium.defined(pickedObject) && pickedObject.id === modelEntity) {
      //     isRotating = true;

      //     // 保存初始方向
      //     initialOrientation = Cesium.Quaternion.clone(
      //       modelEntity.orientation.getValue(viewer.clock.currentTime)
      //     );

      //     const position = modelEntity.position.getValue(
      //       viewer.clock.currentTime
      //     );
      //     const windowPosition =
      //       Cesium.SceneTransforms.wgs84ToWindowCoordinates(
      //         viewer.scene,
      //         position
      //       );

      //     if (windowPosition) {
      //       startAngle = Math.atan2(
      //         movement.position.y - windowPosition.y,
      //         movement.position.x - windowPosition.x
      //       );
      //     }
      //   }
      // }, Cesium.ScreenSpaceEventType.RIGHT_DOWN);

      // handler.setInputAction((movement) => {
      //   if (isRotating && initialOrientation) {
      //     const position = modelEntity.position.getValue(
      //       viewer.clock.currentTime
      //     );
      //     const windowPosition =
      //       Cesium.SceneTransforms.wgs84ToWindowCoordinates(
      //         viewer.scene,
      //         position
      //       );
      //     if (windowPosition) {
      //       const currentAngle = Math.atan2(
      //         movement.endPosition.y - windowPosition.y,
      //         movement.endPosition.x - windowPosition.x
      //       );
      //       const angleDelta = currentAngle - startAngle;

      //       // 从初始方向创建HeadingPitchRoll
      //       const initialHpr =
      //         Cesium.HeadingPitchRoll.fromQuaternion(initialOrientation);

      //       // 计算新的heading值
      //       const newHeading = initialHpr.heading - angleDelta;

      //       // 创建新的方向
      //       const newOrientation = Cesium.Quaternion.fromHeadingPitchRoll(
      //         new Cesium.HeadingPitchRoll(
      //           newHeading,
      //           initialHpr.pitch,
      //           initialHpr.roll
      //         )
      //       );

      //       modelEntity.orientation = newOrientation;

      //       // 获取当前角度并显示
      //       const currentHpr =
      //         Cesium.HeadingPitchRoll.fromQuaternion(newOrientation);
      //       const degrees = Cesium.Math.toDegrees(currentHpr.heading);
      //       // console.log(`当前朝向角度: ${degrees.toFixed(2)}°`);
      //     }
      //   }
      // }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
      // handler.setInputAction(() => {
      //   isRotating = false;
      //   initialOrientation = null;
      // }, Cesium.ScreenSpaceEventType.RIGHT_UP);

      // // 获取当前角度函数
      // function getCurrentHeading() {
      //   return Cesium.Math.toDegrees(modelEntity.heading) || 0;
      // }

      // // 添加UI显示角度
      // const angleDisplay = document.createElement("div");
      // angleDisplay.style.position = "absolute";
      // angleDisplay.style.bottom = "20px";
      // angleDisplay.style.left = "20px";
      // angleDisplay.style.backgroundColor = "white";
      // angleDisplay.style.padding = "5px";
      // viewer.container.appendChild(angleDisplay);

      // // 实时更新角度显示
      // viewer.clock.onTick.addEventListener(function () {
      //   angleDisplay.textContent = `当前角度: ${getCurrentHeading().toFixed(
      //     2
      //   )}°`;
      // });
      // }, 2000);

      // 监听点击事件，拾取坐标
      const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
      handler.setInputAction((e) => {
        const clickPosition = viewer.scene.camera.pickEllipsoid(e.position);
        const randiansPos = Cesium.Cartographic.fromCartesian(clickPosition);
        console.log(
          "经度：" +
            Cesium.Math.toDegrees(randiansPos.longitude) +
            ", 纬度：" +
            Cesium.Math.toDegrees(randiansPos.latitude)
        );
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    },
    setupRotationBehavior() {
      const handler = new Cesium.ScreenSpaceEventHandler(
        this.viewer.scene.canvas
      );

      // 鼠标按下记录起始位置
      handler.setInputAction((movement) => {
        const pickedObject = this.viewer.scene.pick(movement.position);
        if (pickedObject && pickedObject.id === this.entity) {
          this.startMousePosition = movement.position;
        }
      }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

      // 鼠标移动计算旋转
      handler.setInputAction((movement) => {
        if (!this.startMousePosition) return;

        this.currentMousePosition = movement.endPosition;

        // 计算鼠标移动距离（转换为旋转角度）
        const deltaX = this.currentMousePosition.x - this.startMousePosition.x;
        const rotationAngle = deltaX * 0.01; // 灵敏度系数

        // 获取当前朝向四元数
        // const currentOrientation = this.entity.orientation.getValue();

        // 绕Y轴（垂直方向）旋转
        const rotation = Cesium.Quaternion.fromAxisAngle(
          Cesium.Cartesian3.UNIT_Z, // 绕Z轴旋转（水平面）
          rotationAngle
        );

        // 应用新朝向
        // this.entity.orientation = Cesium.Quaternion.multiply(
        //   currentOrientation,
        //   rotation,
        //   new Cesium.Quaternion()
        // );

        // 更新显示数据
        this.updatePositionAndOrientation();
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

      // 鼠标释放重置状态
      handler.setInputAction(() => {
        this.startMousePosition = null;
      }, Cesium.ScreenSpaceEventType.LEFT_UP);
    },
    updatePositionAndOrientation() {
      // 获取当前位置（笛卡尔坐标 → 经纬度）
      // const cartographic = Cesium.Cartographic.fromCartesian(
      //   this.entity.position.getValue()
      // )
      // this.position = {
      //   longitude: Cesium.Math.toDegrees(cartographic.longitude),
      //   latitude: Cesium.Math.toDegrees(cartographic.latitude),
      //   height: cartographic.height
      // }
      // // 获取当前朝向（四元数 → 欧拉角）
      // const orientation = this.entity.orientation.getValue()
      // const hpr = Cesium.HeadingPitchRoll.fromQuaternion(orientation)
      // this.orientation = {
      //   heading: Cesium.Math.toDegrees(hpr.heading),
      //   pitch: Cesium.Math.toDegrees(hpr.pitch),
      //   roll: Cesium.Math.toDegrees(hpr.roll)
      // }
    },
    shuiweiup() {
      // this.activeShapePoints = [];
      // this.floatingPoint = undefined;
      // this.activeShape = undefined;
      // this.handler = this.undefinedisDraw = false;
      // this.maxWaterHeight = 0.2;
      // this.minWaterHeight = 0;
      // this.waterHeight = 0;
      // this.tempEntities = [];
      // viewer.scene.globe.depthTestAgainstTerrain = true;
      // this.activeShapePoints = Line;
      // window.viewer.entities.remove(this.floatingPoint);
      // window.viewer.entities.remove(this.activeShape);
      // this.floatingPoint = undefined;
      // this.activeShape = undefined;
      // this.handler = null;
      // this.induationAnalysis2();
      // this.minWaterHeight = 78;
      // this.primitive.grow();
      // this.renderLoop();
      // this.primitive.extrudedHeight = 78;
      console.log(this.value);
      setTimeout(() => {
        this.primitive.setTargetHeight(Number(this.value));
      }, 3000);

      // console.log(this.aper, this.primitive);
      // this.aper.material.uniforms.waterHeight = 78;
      // this.aper = this.aper.cloned(); // 关键！强制材质更新
      // this.primitive.extrudedHeight = 78;
      // this.primitive.height = 78;
      // this.primitive.targetHeight = 78;
      // this.primitive._extrudedHeight = 78;
      // this.primitive._height = 78;
      // this.primitive._targetHeight = 78;
      // this.primitive.setextrudedHeight(78);
      // const that = this;
      // this.primitive = new WaterPrimitive({
      //   aper: that.aper, //着色器
      //   positions: that.newData, //范围
      //   height: 78, //开始高度
      //   textureCoordinates: that.textureCoordinates, //自定义UV值
      //   speedVal: 0.05, //速度
      //   extrudedHeight: 78,
      //   targetHeight: 78, //最大高度
      //   grow: true, //是否启用动态
      //   upGrow: true, //true 涨水  false 降水
      // });
      // console.log(this.aper, this.primitive);
    },
    huizhiyanmo() {
      // yanmoshow.value = false;
      // buttonshow.value = false;
      // router.push("/");
      // viewer.camera.setView({
      //   destination: Cesium.Cartesian3.fromDegrees(
      //     119.9881430682179,
      //     30.674708206014962,
      //     1267.571673121449
      //   ), // 纬度、经度和高度
      //   orientation: {
      //     heading: 0.3360406546942265,
      //     pitch: -0.43583580983291315,
      //     roll: 6.283149698014369,
      //   },
      // });
      this.activeShapePoints = [];
      this.floatingPoint = undefined;
      this.activeShape = undefined;
      this.handler = this.undefinedisDraw = false;
      this.maxWaterHeight = 0.2;
      this.minWaterHeight = 0;
      this.waterHeight = 0;
      // waterPrimitive = undefined;
      this.tempEntities = [];
      // 开启深度检测
      viewer.scene.globe.depthTestAgainstTerrain = true;
      // this.handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
      // this.handler.setInputAction((event) => {
      //   const earthPosition = viewer.scene.pickPosition(event.position);
      //   if (Cesium.defined(earthPosition)) {
      //     if (this.activeShapePoints.length === 0) {
      //       this.floatingPoint = this.createPoint(earthPosition);
      //       this.activeShapePoints.push(earthPosition);
      //       const dynamicPositions = new Cesium.CallbackProperty(function () {
      //         return new Cesium.PolygonHierarchy(this.activeShapePoints);
      //       }, false);
      //       this.activeShape = this.drawShape(
      //         dynamicPositions,
      //         Cesium.Color.fromBytes(64, 157, 253, 50)
      //       );
      //     }
      //     this.activeShapePoints.push(earthPosition);
      //     this.tempEntities.push(this.createPoint(earthPosition));
      //   }
      // }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
      // this.handler.setInputAction((event) => {
      //   if (Cesium.defined(this.floatingPoint)) {
      //     const newPosition = viewer.scene.pickPosition(event.endPosition);
      //     if (Cesium.defined(newPosition)) {
      //       this.floatingPoint.position.setValue(newPosition);
      //       this.activeShapePoints.pop();
      //       this.activeShapePoints.push(newPosition);
      //     }
      //   }
      // }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

      // this.handler.setInputAction((event) => {
      //   this.activeShapePoints.pop();
      //   if (this.activeShapePoints.length < 3) return;
      this.activeShapePoints = Line;
      // this.tempEntities.push(this.drawPolyline(this.activeShapePoints));
      // let ploy = this.drawShape(
      //   this.activeShapePoints,
      //   Cesium.Color.fromBytes(64, 157, 253, 20)
      // );
      // this.tempEntities.push(ploy);
      // window.viewer.entities.remove(this.floatingPoint);
      // window.viewer.entities.remove(this.activeShape);
      // this.floatingPoint = undefined;
      // this.activeShape = undefined;
      // this.handler.destroy(); // 关闭事件句柄
      // this.handler = null;
      this.induationAnalysis();
      // this.init();
      // }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    },
    clearAllEntities() {
      console.log(viewer.entities.values.length);
      // viewer.entities.removeById("myId");
      viewer.entities.removeAll();
      // viewer.entities.values.forEach((item, index) => {
      //   // 检查每个entity是否有name属性，并且该属性是否等于nameToRemove
      //   if (item.name == "myId") {
      //     // 如果满足条件，则删除该entity
      //     console.log(item);

      //     viewer.entities.remove(item);
      //   }
      // });
      // viewer.entities.removeByName("myId");
      // viewer.camera.setView({
      //   destination: {
      //     x: -2850554.9246458095,
      //     y: 4656672.153306185,
      //     z: 3287574.727124352,
      //   },
      //   orientation: {
      //     heading: Cesium.Math.toRadians(48.72529042457395),
      //     pitch: Cesium.Math.toRadians(-10.899276751527792),
      //     roll: Cesium.Math.toRadians(0.0014027234956804583),
      //   },
      // });
      // positions = [];
      const length = this.tempEntities.length;
      for (let f = 0; f < length; f++) {
        window.viewer.scene.primitives.remove(this.tempEntities[f]);
      }
      this.tempEntities = [];
      this.activeShapePoints = [];
      // warningWaterHeight = 0;
      this.isDraw = !this.isDraw;
      this.floatingPoint = undefined;
      this.activeShape = undefined;
      if (this.handler) {
        this.handler.destroy(); // 关闭事件句柄
        this.handler = undefined;
      }
    },
    createPoint(worldPosition) {
      const point = window.viewer.entities.add({
        name: "myId",
        position: worldPosition,
        point: {
          color: Cesium.Color.SKYBLUE,
          pixelSize: 5,
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
        },
      });
      return point;
    },
    drawShape(positionData, mat) {
      let shape = window.viewer.entities.add({
        polygon: {
          hierarchy: positionData,
          material: mat,
          outline: true,
          outlineColor: Cesium.Color.SKYBLUE,
          outlineWidth: 4,
        },
      });
      return shape;
    },
    drawPolyline(positions) {
      if (positions.length < 1) return;
      console.log(positions, 6666);
      let startP = positions[0];
      let endP = positions[positions.length - 1];
      if (startP.x != endP.x && startP.y != endP.y && startP.z != endP.z)
        positions.push(positions[0]);

      return (this.polylinedata = window.viewer.entities.add({
        name: "polyline",
        id: "myId",
        polyline: {
          positions: positions,
          width: 2.0,
          material: Cesium.Color.SKYBLUE,
          clampToGround: true,
        },
      }));
    },
    async getAreaHeight(positions) {
      let startP = positions[0];
      let endP = positions[positions.length - 1];
      if (startP.x != endP.x && startP.y != endP.y && startP.z != endP.z)
        positions.push(positions[0]);

      const tempPoints = [];
      for (let i = 0; i < positions.length; i++) {
        var ellipsoid = window.viewer.scene.globe.ellipsoid;
        var cartographic = ellipsoid.cartesianToCartographic(positions[i]);
        var lat = Cesium.Math.toDegrees(cartographic.latitude);
        var lng = Cesium.Math.toDegrees(cartographic.longitude);
        tempPoints.push([lng, lat]);
      }
      var line = turf.lineString(tempPoints);
      var chunk = turf.lineChunk(line, 10, {
        units: "meters",
      });

      const tempArray = [];
      chunk.features.forEach((f) => {
        f.geometry.coordinates.forEach((c) => {
          tempArray.push(Cesium.Cartographic.fromDegrees(c[0], c[1]));
        });
      });

      var promise = Cesium.sampleTerrainMostDetailed(
        window.viewer.terrainProvider,
        tempArray
      );
      const updatedPositions = await Cesium.sampleTerrainMostDetailed(
        window.viewer.terrainProvider,
        tempArray
      ); // 计算取样点的高度
      let minHeight = 60;
      let maxHeight = 70;
      // 计算取样点的最小高度和最大高度
      // for (let i = 0; i < updatedPositions.length; i++) {
      //   const height = updatedPositions[i].height;
      //   // console.log(height);
      //   if (height < minHeight) {
      //     minHeight = height;
      //   }
      //   if (height > maxHeight) {
      //     maxHeight = height;
      //   }
      // }
      this.waterHeight = Math.ceil(minHeight);
      this.minWaterHeight = Math.ceil(minHeight);
      this.maxWaterHeight = Math.ceil(maxHeight);
      // 禁用绘制按钮
      this.isDraw = !this.isDraw;
      return {
        minHeight,
        maxHeight,
      };
    },
    async induationAnalysis() {
      await this.getAreaHeight(this.activeShapePoints);
      // if (Number(warningWaterHeight) < Number(this.minWaterHeight) || Number(warningWaterHeight) > Number(maxWaterHeight)) {
      // 	$message({
      // 		message: '预警高度必须在最小高度和最小高度之间',
      // 		type: 'warning'
      // 	});
      // 	return
      // }
      let newData = [];
      let positionsArr = [];
      for (let i = 0; i < this.activeShapePoints.length; i++) {
        if (i < this.activeShapePoints.length - 1) {
          let cartographic = Cesium.Cartographic.fromCartesian(
            this.activeShapePoints[i]
          );
          newData.push(
            parseFloat(
              Cesium.Math.toDegrees(cartographic.longitude).toFixed(6)
            ),
            parseFloat(Cesium.Math.toDegrees(cartographic.latitude).toFixed(6)),
            0
          );
          if (i == 0) {
            positionsArr.push(new Cesium.Cartesian2(0, 1));
          } else {
            if (i % 3 == 1) {
              positionsArr.push(new Cesium.Cartesian2(0, 0));
            } else if (i % 3 == 2) {
              positionsArr.push(new Cesium.Cartesian2(1, 0));
            } else if (i % 3 == 0) {
              positionsArr.push(new Cesium.Cartesian2(1, 1));
            }
          }
        }
      }
      this.newData = newData;
      // console.log(positionsArr);
      let textureCoordinates = {
        positions: positionsArr,
      };
      this.textureCoordinates = textureCoordinates;
      // console.log(newData);
      this.aper = new Cesium.MaterialAppearance({
        material: new Cesium.Material({
          fabric: {
            type: "Water",
            uniforms: {
              baseWaterColor: new Cesium.Color(
                64 / 255.0,
                157 / 255.0,
                253 / 255.0,
                0.5
              ),
              normalMap: "./jk.jpeg",
              frequency: 1000.0,
              animationSpeed: 0.1,
              amplitude: 10,
              specularIntensity: 10,
            },

            // uniforms: {
            //   waterHeight: 70, // 仅通过此uniform控制水位
            //   iTime: 0,
            //   SEA_SPEED: 0.2, //流速
            //   SEA_DIRECTION: Cesium.Cartesian2.normalize(
            //     // new Cesium.Cartesian2(0, 1),
            //     // new Cesium.Cartesian2(0, 0),
            //     // new Cesium.Cartesian2(1, 0),
            //     // new Cesium.Cartesian2(1, 1)
            //     new Cesium.Cartesian2(1.0, 0.0),
            //     new Cesium.Cartesian2()
            //   ), //流向
            //   EL: 1.1, //深度
            // },
            //       source: `
            // 		const int NUM_STEPS = 8;
            // 	  const float PI     = 3.141592;
            // 	  const float EPSILON  = 1e-3;
            // 	  //#define EPSILON_NRM (0.1 / iResolution.x)
            // 	  #define EPSILON_NRM (0.1 / 200.0)

            // 	  // sea  海洋参数
            // 	  const int ITER_GEOMETRY = 3;    //定义几何迭代次数。在计算几何着色器中，这决定了波浪细节的精细程度。更高的值会生成更复杂的几何形状，但也会增加计算成本
            // 	  const int ITER_FRAGMENT = 25;   //定义片段迭代次数。这控制了片段着色器中计算波浪细节的复杂度。同样，更高的值会带来更精细的效果，但也意味着更多的计算
            // 	  const float SEA_HEIGHT = 0.19;   //海浪的高度
            // 	  const float SEA_CHOPPY = 0.015;    //海面的“粗糙度”或波浪的强度
            // 	 // const float SEA_SPEED = 0.8;      //流速
            // 	  const float SEA_FREQ = 3.56;    //定义海浪的频率。这决定了波浪在单位距离内出现的次数，影响着海面波动的密集程度。
            // 	  // const vec3 SEA_BASE = vec3(0.1,0.19,0.22);    //定义海水的基础颜色。这个向量包含了红、绿、蓝三个通道的颜色值，用于渲染水体的基本色调
            // 	  const vec3 SEA_BASE = vec3(0.1, 0.2, 0.2);    //定义海水的基础颜色。这个向量包含了红、绿、蓝三个通道的颜色值，用于渲染水体的基本色调
            // 	  // const vec3 SEA_WATER_COLOR = vec3(0.8,0.9,0.5);     //定义海水的颜色。不同于基础颜色，这个变量可能在着色器中用于调整水体在不同光照条件下的颜色表现，例如反射天空的颜色。
            // 	   const vec3 SEA_WATER_COLOR = vec3(59.0 / 255.0, 64.0 / 255.0, 49.0 / 255.0);    //定义海水的基础颜色。这个向量包含了红、绿、蓝三个通道的颜色值，用于渲染水体的基本色调
            // 	  //#define SEA_TIME (1.0 + iTime * SEA_SPEED)

            // 	  const mat2 octave_m = mat2(1.6,1.2,-1.2,1.6);

            // 	  // math 数学函数  // 从欧拉角转换为旋转矩阵
            // 	  mat3 fromEuler(vec3 ang) {
            // 		vec2 a1 = vec2(sin(ang.x),cos(ang.x));
            // 		vec2 a2 = vec2(sin(ang.y),cos(ang.y));
            // 		vec2 a3 = vec2(sin(ang.z),cos(ang.z));
            // 		mat3 m;
            // 		m[0] = vec3(a1.y*a3.y+a1.x*a2.x*a3.x,a1.y*a2.x*a3.x+a3.y*a1.x,-a2.y*a3.x);
            // 		m[1] = vec3(-a2.y*a1.x,a1.y*a2.y,a2.x);
            // 		m[2] = vec3(a3.y*a1.x*a2.x+a1.y*a3.x,a1.x*a3.x-a1.y*a3.y*a2.x,a2.y*a3.y);
            // 		return m;
            // 	  }
            // 	  // 哈希函数
            // 	  float hash( vec2 p ) {
            // 		float h = dot(p,vec2(127.1,311.7));
            // 		return fract(sin(h)*43758.5453123);
            // 	  }
            // 	  // 噪声函数
            // 	  float noise( in vec2 p ) {
            // 		vec2 i = floor( p );
            // 		vec2 f = fract( p );
            // 		vec2 u = f*f*(3.0-2.0*f);
            // 		return -1.0+2.0*mix( mix( hash( i + vec2(0.0,0.0) ),
            // 				 hash( i + vec2(1.0,0.0) ), u.x),
            // 			  mix( hash( i + vec2(0.0,1.0) ),
            // 				 hash( i + vec2(1.0,1.0) ), u.x), u.y);
            // 	  }

            // 	  // 光照函数
            // 	  // 扩散反射
            // 	  float diffuse(vec3 n,vec3 l,float p) {
            // 		return pow(dot(n,l) * 0.4 + 0.6,p);
            // 	  }
            // 	  // 镜面反射
            // 	  float specular(vec3 n,vec3 l,vec3 e,float s) {
            // 		float nrm = (s + 8.0) / (PI * 8.0);
            // 		return pow(max(dot(reflect(e,n),l),0.0),s) * nrm;
            // 	  }

            // 	  // sky // 天空颜色函数
            // 	  vec3 getSkyColor(vec3 e) {
            // 		e.y = max(e.y,0.0);
            // 		return vec3(pow(1.0-e.y,2.0), 1.0-e.y, 0.6+(1.0-e.y)*0.4);
            // 	  }

            // 	  // 海洋相关函数
            // 	  // 单一频段海洋波动
            // 	  float sea_octave(vec2 uv, float choppy) {
            // 		uv += noise(uv);
            // 		vec2 wv = 1.0-abs(sin(uv));
            // 		vec2 swv = abs(cos(uv));
            // 		wv = mix(wv,swv,wv);
            // 		return pow(1.0-pow(wv.x * wv.y,0.65),choppy);
            // 	  }
            // // 地形映射
            // 	  float map(vec3 p) {
            // 		float freq = SEA_FREQ;
            // 		float amp = SEA_HEIGHT;
            // 		float choppy = SEA_CHOPPY;
            // 		vec2 uv = p.xz;
            // 		uv.x *= 0.75;
            // 		float d, h = 0.0;
            // 		// float SEA_TIME = 1.0 + iTime * SEA_SPEED;
            // 		//todu 新加的
            // 		float SEA_TIME = 1.0 + dot(SEA_DIRECTION, vec2(iTime * SEA_SPEED, 0.0));

            // 		for(int i = 0; i < ITER_GEOMETRY; i++) {
            // 		  d = sea_octave((uv+SEA_TIME)*freq,choppy);
            // 		  d += sea_octave((uv-SEA_TIME)*freq,choppy);
            // 		  // h += d * amp;
            // 		  //todu 新加的
            // 		   h += d * amp * EL;
            // 		  uv *= octave_m; freq *= 1.9; amp *= 0.22;
            // 		  choppy = mix(choppy,1.0,0.2);
            // 		}
            // 		return p.y - h;
            // 	  }
            // // 详细地形映射
            // 	  float map_detailed(vec3 p) {
            // 		float freq = SEA_FREQ;
            // 		float amp = SEA_HEIGHT;
            // 		float choppy = SEA_CHOPPY;
            // 		vec2 uv = p.xz; uv.x *= 0.75;

            // 		 // float SEA_TIME = 1.0 + iTime * SEA_SPEED;
            // 		 float SEA_TIME = 1.0 + dot(SEA_DIRECTION, vec2(iTime * SEA_SPEED, 0.0));
            // 		float d, h = 0.0;
            // 		for(int i = 0; i < ITER_FRAGMENT; i++) {
            // 		  d = sea_octave((uv+SEA_TIME)*freq,choppy);
            // 		  d += sea_octave((uv-SEA_TIME)*freq,choppy);
            // 		  // h += d * amp;
            // 			h += d * amp * EL;
            // 		  uv *= octave_m; freq *= 1.9; amp *= 0.22;
            // 		  choppy = mix(choppy,1.0,0.2);
            // 		}
            // 		return p.y - h;
            // 	  }
            // // 获取海洋颜色
            // 	  vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye, vec3 dist) {
            // 		float fresnel = clamp(1.0 - dot(n,-eye), 0.0, 1.0);
            // 		fresnel = pow(fresnel,3.0) * 0.65;

            // 		vec3 reflected = getSkyColor(reflect(eye,n));
            // 		vec3 refracted = SEA_BASE + diffuse(n,l,80.0) * SEA_WATER_COLOR * 0.12;

            // 		vec3 color = mix(refracted,reflected,fresnel);

            // 		float atten = max(1.0 - dot(dist,dist) * 0.001, 0.0);
            // 		color += SEA_WATER_COLOR * (p.y - SEA_HEIGHT) * 0.18 * atten;

            // 		color += vec3(specular(n,l,eye,60.0));

            // 		return color;
            // 	  }

            // 	  // tracing// 光线追踪函数
            // 	   // 获取法线
            // 	  vec3 getNormal(vec3 p, float eps) {
            // 		vec3 n;
            // 		n.y = map_detailed(p);
            // 		n.x = map_detailed(vec3(p.x+eps,p.y,p.z)) - n.y;
            // 		n.z = map_detailed(vec3(p.x,p.y,p.z+eps)) - n.y;
            // 		n.y = eps;
            // 		return normalize(n);
            // 	  }
            // // 高度图追踪
            // 	  float heightMapTracing(vec3 ori, vec3 dir, out vec3 p) {
            // 		float tm = 0.0;
            // 		float tx = 1000.0;
            // 		float hx = map(ori + dir * tx);
            // 		if(hx > 0.0) return tx;
            // 		float hm = map(ori + dir * tm);
            // 		float tmid = 0.0;
            // 		for(int i = 0; i < NUM_STEPS; i++) {
            // 		  tmid = mix(tm,tx, hm/(hm-hx));
            // 		  p = ori + dir * tmid;
            // 		  float hmid = map(p);
            // 		  if(hmid < 0.0) {
            // 			tx = tmid;
            // 			hx = hmid;
            // 		  } else {
            // 			tm = tmid;
            // 			hm = hmid;
            // 		  }
            // 		}
            // 		return tmid;
            // 	  }
            // 			// 主要材质函数
            // 		   vec4 czm_getMaterial(vec2 vUv)
            // 		   {
            // 			vec2 uv = vUv;
            // 			//todo 新加
            // 			//   vec2 uv = vUv + iTime * SEA_SPEED * SEA_DIRECTION.xy;

            // 			 float time = iTime * 0.3;
            // 			 float el = EL;
            // 			 // 使用SEA_DIRECTION和SEA_SPEED来控制河流流动
            // 			 float SEA_TIME = 1.0 + dot(SEA_DIRECTION, vec2(iTime * SEA_SPEED, 0.0));
            // 			// uv = vUv * 2.0 - 1.0;
            // 			// float time = iTime * 0.3 + 0.0*0.01;

            // 			// ray
            // 			vec3 ang = vec3(0, 1.2, 0.0);
            // 			  vec3 ori = vec3(0.0,3.5,0);
            // 			vec3 dir = normalize(vec3(uv.xy,-2.0)); dir.z += length(uv) * 0.15;
            // 			dir = normalize(dir) * fromEuler(ang);

            // 			// tracing
            // 			vec3 p;
            // 			heightMapTracing(ori,dir,p);
            // 			vec3 dist = p - ori;
            // 			vec3 n = getNormal(p, dot(dist,dist) * EPSILON_NRM);
            // 			vec3 light = normalize(vec3(0.0,1.0,0.8));
            // 			// color
            // 			vec3 color = mix(
            // 			  getSkyColor(dir),
            // 			  getSeaColor(p,n,light,dir,dist),
            // 			  pow(smoothstep(0.0,-0.05,dir.y),0.3)
            // 			  );
            // 			  //设置透明度
            // 			   float alpha = 0.5;
            // 			   return vec4( pow(color,vec3(0.75)),alpha);
            // 		   }
            // 		`,
          },
        }),
        // translucent: true,
        // vertexShaderSource: `
        // 	in vec3 position3DHigh;
        // 	in vec3 position3DLow;
        // 	in float batchId;
        // 	in vec2 st;
        // 	in vec3 normal;
        // 	out vec2 v_st;
        // 	out vec3 v_positionEC;
        // 	out vec3 v_normalEC;

        // 	void main() {
        // 		v_st = st;

        // 		vec4 p = czm_computePosition();

        // 		v_positionEC = (czm_modelViewRelativeToEye * p).xyz;      // position in eye coordinates
        // 		v_normalEC = czm_normal * normal;                         // normal in eye coordinates

        // 		gl_Position = czm_modelViewProjectionRelativeToEye * p;
        // 	}
        // 				`,
        // fragmentShaderSource: `
        //   in vec2 v_st;
        //   in vec3 v_positionEC;
        //   in vec3 v_normalEC;
        //   void main()  {
        // 	vec3 positionToEyeEC = -v_positionEC;
        // 	vec3 normalEC = normalize(v_normalEC);
        // 	czm_materialInput materialInput;
        // 	materialInput.normalEC = normalEC;
        // 	materialInput.positionToEyeEC = positionToEyeEC;
        // 	materialInput.st = v_st;
        // 	vec4 color = czm_getMaterial(v_st);
        // 	out_FragColor = color;
        //   }
        // 			`,
      });
      const that = this;
      this.primitive = new WaterPrimitive({
        aper: that.aper, //着色器
        positions: newData, //范围
        height: Number(this.minWaterHeight), //开始高度
        textureCoordinates: textureCoordinates, //自定义UV值
        speedVal: 0.05, //速度
        extrudedHeight: Number(this.minWaterHeight),
        targetHeight: Number(this.maxWaterHeight), //最大高度
        grow: true, //是否启用动态
        upGrow: true, //true 涨水  false 降水
      });

      let primitArr = viewer.scene.primitives.add(this.primitive);
      this.tempEntities.push(primitArr);
      function renderLoop(timestamp) {
        that.aper.material.uniforms.iTime = timestamp / 1000;
        requestAnimationFrame(renderLoop);
      }
      renderLoop();
    },
    renderLoop(timestamp) {
      this.aper.material.uniforms.iTime = timestamp / 1000;
      requestAnimationFrame(this.renderLoop);
    },
    async induationAnalysis2() {
      await this.getAreaHeight2(this.activeShapePoints);
      // if (Number(warningWaterHeight) < Number(this.minWaterHeight) || Number(warningWaterHeight) > Number(maxWaterHeight)) {
      // 	$message({
      // 		message: '预警高度必须在最小高度和最小高度之间',
      // 		type: 'warning'
      // 	});
      // 	return
      // }
      let newData = [];
      let positionsArr = [];
      for (let i = 0; i < this.activeShapePoints.length; i++) {
        if (i < this.activeShapePoints.length - 1) {
          let cartographic = Cesium.Cartographic.fromCartesian(
            this.activeShapePoints[i]
          );
          newData.push(
            parseFloat(
              Cesium.Math.toDegrees(cartographic.longitude).toFixed(6)
            ),
            parseFloat(Cesium.Math.toDegrees(cartographic.latitude).toFixed(6)),
            0
          );
          if (i == 0) {
            positionsArr.push(new Cesium.Cartesian2(0, 1));
          } else {
            if (i % 3 == 1) {
              positionsArr.push(new Cesium.Cartesian2(0, 0));
            } else if (i % 3 == 2) {
              positionsArr.push(new Cesium.Cartesian2(1, 0));
            } else if (i % 3 == 0) {
              positionsArr.push(new Cesium.Cartesian2(1, 1));
            }
          }
        }
      }
      // console.log(positionsArr);
      let textureCoordinates = {
        positions: positionsArr,
      };
      // console.log(newData);
      let aper = new Cesium.MaterialAppearance({
        material: new Cesium.Material({
          fabric: {
            uniforms: {
              iTime: 0,
              SEA_SPEED: 0.2, //流速
              SEA_DIRECTION: Cesium.Cartesian2.normalize(
                // new Cesium.Cartesian2(0, 1),
                // new Cesium.Cartesian2(0, 0),
                // new Cesium.Cartesian2(1, 0),
                // new Cesium.Cartesian2(1, 1)
                new Cesium.Cartesian2(1.0, 0.0),
                new Cesium.Cartesian2()
              ), //流向
              EL: 1.1, //深度
            },
            source: `
					const int NUM_STEPS = 8;
				  const float PI     = 3.141592;
				  const float EPSILON  = 1e-3;
				  //#define EPSILON_NRM (0.1 / iResolution.x)
				  #define EPSILON_NRM (0.1 / 200.0)
			
				  // sea  海洋参数
				  const int ITER_GEOMETRY = 3;    //定义几何迭代次数。在计算几何着色器中，这决定了波浪细节的精细程度。更高的值会生成更复杂的几何形状，但也会增加计算成本
				  const int ITER_FRAGMENT = 25;   //定义片段迭代次数。这控制了片段着色器中计算波浪细节的复杂度。同样，更高的值会带来更精细的效果，但也意味着更多的计算
				  const float SEA_HEIGHT = 0.19;   //海浪的高度
				  const float SEA_CHOPPY = 0.015;    //海面的“粗糙度”或波浪的强度
				 // const float SEA_SPEED = 0.8;      //流速
				  const float SEA_FREQ = 3.56;    //定义海浪的频率。这决定了波浪在单位距离内出现的次数，影响着海面波动的密集程度。
				  // const vec3 SEA_BASE = vec3(0.1,0.19,0.22);    //定义海水的基础颜色。这个向量包含了红、绿、蓝三个通道的颜色值，用于渲染水体的基本色调
				  const vec3 SEA_BASE = vec3(0.1, 0.2, 0.2);    //定义海水的基础颜色。这个向量包含了红、绿、蓝三个通道的颜色值，用于渲染水体的基本色调
				  // const vec3 SEA_WATER_COLOR = vec3(0.8,0.9,0.5);     //定义海水的颜色。不同于基础颜色，这个变量可能在着色器中用于调整水体在不同光照条件下的颜色表现，例如反射天空的颜色。
				   const vec3 SEA_WATER_COLOR = vec3(59.0 / 255.0, 64.0 / 255.0, 49.0 / 255.0);    //定义海水的基础颜色。这个向量包含了红、绿、蓝三个通道的颜色值，用于渲染水体的基本色调
				  //#define SEA_TIME (1.0 + iTime * SEA_SPEED)
			
				  const mat2 octave_m = mat2(1.6,1.2,-1.2,1.6);
			
				  // math 数学函数  // 从欧拉角转换为旋转矩阵
				  mat3 fromEuler(vec3 ang) {
					vec2 a1 = vec2(sin(ang.x),cos(ang.x));
					vec2 a2 = vec2(sin(ang.y),cos(ang.y));
					vec2 a3 = vec2(sin(ang.z),cos(ang.z));
					mat3 m;
					m[0] = vec3(a1.y*a3.y+a1.x*a2.x*a3.x,a1.y*a2.x*a3.x+a3.y*a1.x,-a2.y*a3.x);
					m[1] = vec3(-a2.y*a1.x,a1.y*a2.y,a2.x);
					m[2] = vec3(a3.y*a1.x*a2.x+a1.y*a3.x,a1.x*a3.x-a1.y*a3.y*a2.x,a2.y*a3.y);
					return m;
				  }
				  // 哈希函数
				  float hash( vec2 p ) {
					float h = dot(p,vec2(127.1,311.7));
					return fract(sin(h)*43758.5453123);
				  }
				  // 噪声函数
				  float noise( in vec2 p ) {
					vec2 i = floor( p );
					vec2 f = fract( p );
					vec2 u = f*f*(3.0-2.0*f);
					return -1.0+2.0*mix( mix( hash( i + vec2(0.0,0.0) ),
							 hash( i + vec2(1.0,0.0) ), u.x),
						  mix( hash( i + vec2(0.0,1.0) ),
							 hash( i + vec2(1.0,1.0) ), u.x), u.y);
				  }
			
				  // 光照函数
				  // 扩散反射
				  float diffuse(vec3 n,vec3 l,float p) {
					return pow(dot(n,l) * 0.4 + 0.6,p);
				  }
				  // 镜面反射
				  float specular(vec3 n,vec3 l,vec3 e,float s) {
					float nrm = (s + 8.0) / (PI * 8.0);
					return pow(max(dot(reflect(e,n),l),0.0),s) * nrm;
				  }
			
				  // sky // 天空颜色函数
				  vec3 getSkyColor(vec3 e) {
					e.y = max(e.y,0.0);
					return vec3(pow(1.0-e.y,2.0), 1.0-e.y, 0.6+(1.0-e.y)*0.4);
				  }
			
				  // 海洋相关函数
				  // 单一频段海洋波动
				  float sea_octave(vec2 uv, float choppy) {
					uv += noise(uv);
					vec2 wv = 1.0-abs(sin(uv));
					vec2 swv = abs(cos(uv));
					wv = mix(wv,swv,wv);
					return pow(1.0-pow(wv.x * wv.y,0.65),choppy);
				  }
			// 地形映射
				  float map(vec3 p) {
					float freq = SEA_FREQ;
					float amp = SEA_HEIGHT;
					float choppy = SEA_CHOPPY;
					vec2 uv = p.xz;
					uv.x *= 0.75;
					float d, h = 0.0;
					// float SEA_TIME = 1.0 + iTime * SEA_SPEED;
					//todu 新加的
					float SEA_TIME = 1.0 + dot(SEA_DIRECTION, vec2(iTime * SEA_SPEED, 0.0));
			
					for(int i = 0; i < ITER_GEOMETRY; i++) {
					  d = sea_octave((uv+SEA_TIME)*freq,choppy);
					  d += sea_octave((uv-SEA_TIME)*freq,choppy);
					  // h += d * amp;
					  //todu 新加的
					   h += d * amp * EL;
					  uv *= octave_m; freq *= 1.9; amp *= 0.22;
					  choppy = mix(choppy,1.0,0.2);
					}
					return p.y - h;
				  }
			// 详细地形映射
				  float map_detailed(vec3 p) {
					float freq = SEA_FREQ;
					float amp = SEA_HEIGHT;
					float choppy = SEA_CHOPPY;
					vec2 uv = p.xz; uv.x *= 0.75;
			
					 // float SEA_TIME = 1.0 + iTime * SEA_SPEED;
					 float SEA_TIME = 1.0 + dot(SEA_DIRECTION, vec2(iTime * SEA_SPEED, 0.0));
					float d, h = 0.0;
					for(int i = 0; i < ITER_FRAGMENT; i++) {
					  d = sea_octave((uv+SEA_TIME)*freq,choppy);
					  d += sea_octave((uv-SEA_TIME)*freq,choppy);
					  // h += d * amp;
						h += d * amp * EL;
					  uv *= octave_m; freq *= 1.9; amp *= 0.22;
					  choppy = mix(choppy,1.0,0.2);
					}
					return p.y - h;
				  }
			// 获取海洋颜色
				  vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye, vec3 dist) {
					float fresnel = clamp(1.0 - dot(n,-eye), 0.0, 1.0);
					fresnel = pow(fresnel,3.0) * 0.65;
			
					vec3 reflected = getSkyColor(reflect(eye,n));
					vec3 refracted = SEA_BASE + diffuse(n,l,80.0) * SEA_WATER_COLOR * 0.12;
			
					vec3 color = mix(refracted,reflected,fresnel);
			
					float atten = max(1.0 - dot(dist,dist) * 0.001, 0.0);
					color += SEA_WATER_COLOR * (p.y - SEA_HEIGHT) * 0.18 * atten;
			
					color += vec3(specular(n,l,eye,60.0));
			
					return color;
				  }
			
				  // tracing// 光线追踪函数
				   // 获取法线
				  vec3 getNormal(vec3 p, float eps) {
					vec3 n;
					n.y = map_detailed(p);
					n.x = map_detailed(vec3(p.x+eps,p.y,p.z)) - n.y;
					n.z = map_detailed(vec3(p.x,p.y,p.z+eps)) - n.y;
					n.y = eps;
					return normalize(n);
				  }
			// 高度图追踪
				  float heightMapTracing(vec3 ori, vec3 dir, out vec3 p) {
					float tm = 0.0;
					float tx = 1000.0;
					float hx = map(ori + dir * tx);
					if(hx > 0.0) return tx;
					float hm = map(ori + dir * tm);
					float tmid = 0.0;
					for(int i = 0; i < NUM_STEPS; i++) {
					  tmid = mix(tm,tx, hm/(hm-hx));
					  p = ori + dir * tmid;
					  float hmid = map(p);
					  if(hmid < 0.0) {
						tx = tmid;
						hx = hmid;
					  } else {
						tm = tmid;
						hm = hmid;
					  }
					}
					return tmid;
				  }
						// 主要材质函数
					   vec4 czm_getMaterial(vec2 vUv)
					   {
						vec2 uv = vUv;
						//todo 新加
						//   vec2 uv = vUv + iTime * SEA_SPEED * SEA_DIRECTION.xy;
			
						 float time = iTime * 0.3;
						 float el = EL;
						 // 使用SEA_DIRECTION和SEA_SPEED来控制河流流动
						 float SEA_TIME = 1.0 + dot(SEA_DIRECTION, vec2(iTime * SEA_SPEED, 0.0));
						// uv = vUv * 2.0 - 1.0;
						// float time = iTime * 0.3 + 0.0*0.01;
			
						// ray
						vec3 ang = vec3(0, 1.2, 0.0);
						  vec3 ori = vec3(0.0,3.5,0);
						vec3 dir = normalize(vec3(uv.xy,-2.0)); dir.z += length(uv) * 0.15;
						dir = normalize(dir) * fromEuler(ang);
			
						// tracing
						vec3 p;
						heightMapTracing(ori,dir,p);
						vec3 dist = p - ori;
						vec3 n = getNormal(p, dot(dist,dist) * EPSILON_NRM);
						vec3 light = normalize(vec3(0.0,1.0,0.8));
						// color
						vec3 color = mix(
						  getSkyColor(dir),
						  getSeaColor(p,n,light,dir,dist),
						  pow(smoothstep(0.0,-0.05,dir.y),0.3)
						  );
						  //设置透明度
						   float alpha = 0.5;
						   return vec4( pow(color,vec3(0.75)),alpha);
					   }
					`,
          },
        }),
        translucent: true,
        vertexShaderSource: `
					in vec3 position3DHigh;
					in vec3 position3DLow;
					in float batchId;
					in vec2 st;
					in vec3 normal;
					out vec2 v_st;
					out vec3 v_positionEC;
					out vec3 v_normalEC;
			
					void main() {
						v_st = st;
			
						vec4 p = czm_computePosition();
			
						v_positionEC = (czm_modelViewRelativeToEye * p).xyz;      // position in eye coordinates
						v_normalEC = czm_normal * normal;                         // normal in eye coordinates
			
						gl_Position = czm_modelViewProjectionRelativeToEye * p;
					}
								`,
        fragmentShaderSource: `
				  in vec2 v_st;
				  in vec3 v_positionEC;
				  in vec3 v_normalEC;
				  void main()  {
					vec3 positionToEyeEC = -v_positionEC;
					vec3 normalEC = normalize(v_normalEC);
					czm_materialInput materialInput;
					materialInput.normalEC = normalEC;
					materialInput.positionToEyeEC = positionToEyeEC;
					materialInput.st = v_st;
					vec4 color = czm_getMaterial(v_st);
					out_FragColor = color;
				  }
							`,
      });

      let primitive = new WaterPrimitive({
        aper: aper, //着色器
        positions: newData, //范围
        height: Number(this.minWaterHeight), //开始高度
        textureCoordinates: textureCoordinates, //自定义UV值
        speedVal: 0.05, //速度
        extrudedHeight: Number(this.minWaterHeight),
        targetHeight: Number(this.maxWaterHeight), //最大高度
        grow: true, //是否启用动态
        upGrow: true, //true 涨水  false 降水
      });

      let primitArr = viewer.scene.primitives.add(primitive);
      this.tempEntities.push(primitArr);
      function renderLoop(timestamp) {
        aper.material.uniforms.iTime = timestamp / 1000;
        requestAnimationFrame(renderLoop);
      }
      renderLoop();
    },
    async getAreaHeight2(positions) {
      let startP = positions[0];
      let endP = positions[positions.length - 1];
      if (startP.x != endP.x && startP.y != endP.y && startP.z != endP.z)
        positions.push(positions[0]);

      const tempPoints = [];
      for (let i = 0; i < positions.length; i++) {
        var ellipsoid = window.viewer.scene.globe.ellipsoid;
        var cartographic = ellipsoid.cartesianToCartographic(positions[i]);
        var lat = Cesium.Math.toDegrees(cartographic.latitude);
        var lng = Cesium.Math.toDegrees(cartographic.longitude);
        tempPoints.push([lng, lat]);
      }
      var line = turf.lineString(tempPoints);
      var chunk = turf.lineChunk(line, 10, {
        units: "meters",
      });

      const tempArray = [];
      chunk.features.forEach((f) => {
        f.geometry.coordinates.forEach((c) => {
          tempArray.push(Cesium.Cartographic.fromDegrees(c[0], c[1]));
        });
      });

      var promise = Cesium.sampleTerrainMostDetailed(
        window.viewer.terrainProvider,
        tempArray
      );
      const updatedPositions = await Cesium.sampleTerrainMostDetailed(
        window.viewer.terrainProvider,
        tempArray
      ); // 计算取样点的高度
      let minHeight = 70;
      let maxHeight = 70 + Number(this.value);
      // 计算取样点的最小高度和最大高度
      // for (let i = 0; i < updatedPositions.length; i++) {
      //   const height = updatedPositions[i].height;
      //   // console.log(height);
      //   if (height < minHeight) {
      //     minHeight = height;
      //   }
      //   if (height > maxHeight) {
      //     maxHeight = height;
      //   }
      // }
      this.waterHeight = Math.ceil(minHeight);
      this.minWaterHeight = Math.ceil(minHeight);
      this.maxWaterHeight = Math.ceil(maxHeight);
      // 禁用绘制按钮
      this.isDraw = !this.isDraw;
      return {
        minHeight,
        maxHeight,
      };
    },
    init() {
      // handler = new Cesium.ScreenSpaceEventHandler(window.viewer.canvas);
      const position = Cesium.Cartesian3.fromDegrees(
        112.73959663183864,
        31.135803413150533,
        100
      );
      const modelMatrix = Cesium.Matrix4.fromTranslation(position);

      // 创建旋转矩阵（使朝向东方）
      const rotation = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(-90));
      Cesium.Matrix4.multiplyByMatrix3(modelMatrix, rotation, modelMatrix);
      const _this = this;
      viewer.clock.shouldAnimate = true;
      viewer.scene.globe.depthTestAgainstTerrain = true;
      viewer.trackedEntity = this.entity;
      var particleSystem = this.scene.primitives.add(
        new Cesium.ParticleSystem({
          image: require("@/assets/water10.png"), //生成所需粒子的图片路径
          //粒子在生命周期开始时的颜色
          startColor: new Cesium.Color(1, 1, 1, 0.6),
          //粒子在生命周期结束时的颜色
          endColor: new Cesium.Color(0.8, 0.86, 1, 0.4),
          //粒子在生命周期开始时初始比例
          startScale: _this.viewModel.startScale,
          //粒子在生命周期结束时比例
          endScale: _this.viewModel.endScale,
          //粒子发射的最小速度
          minimumParticleLife: _this.viewModel.minimumParticleLife,
          //粒子发射的最大速度
          maximumParticleLife: _this.viewModel.maximumParticleLife,
          //粒子质量的最小界限
          minimumSpeed: _this.viewModel.minimumSpeed,
          //粒子质量的最大界限
          maximumSpeed: _this.viewModel.maximumSpeed,
          // speed: 0.00006,
          //以像素为单位缩放粒子图像尺寸
          imageSize: new Cesium.Cartesian2(
            _this.viewModel.particleSize,
            _this.viewModel.particleSize
          ),
          velocity: new Cesium.Cartesian3(78, 90, 50), // X,Y,Z方向的速度分量
          //每秒发射的粒子数
          emissionRate: _this.viewModel.emissionRate,
          particleLife: 8, // 单个粒子的生命周期（秒）
          //粒子系统发射粒子的时间（秒）
          lifetime: 10,
          //设置粒子的大小是否以米或像素为单位
          sizeInMeters: true,
          loop: true, // 循环发射粒子
          //系统的粒子发射器
          emitter: new Cesium.CircleEmitter(0.5), //BoxEmitter 盒形发射器，ConeEmitter 锥形发射器，SphereEmitter 球形发射器，CircleEmitter圆形发射器
          // 模型矩阵：将粒子系统从模型坐标系转换到世界坐标系
          // modelMatrix: new Cesium.Matrix4.fromTranslation(
          //   viewer.scene.camera.position
          // ),
          // emitterModelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(
          //   Cesium.Cartesian3.fromDegrees(
          //     113.13997310488757,
          //     41.04611373496531,
          //     50
          //   )
          // ), //这个矩阵用于定义粒发射器在世界空间中的位置和方向。
          //回调函数，实现各种喷泉、烟雾效果
          // modelMatrix: modelMatrix,
          emitterModelMatrix: computeEmitterModelMatrix(45, 30, 0), // 朝向45度，俯仰30度(),
          updateCallback: (p, dt) => {
            return this.applyGravity(p, dt);
          },
        })
      );
      // 计算发射器模型矩阵（控制朝向）
      function computeEmitterModelMatrix(heading, pitch, roll) {
        const hpr = new Cesium.HeadingPitchRoll(
          Cesium.Math.toRadians(heading),
          Cesium.Math.toRadians(pitch),
          Cesium.Math.toRadians(roll)
        );

        const translationRotationScale = new Cesium.TranslationRotationScale(
          Cesium.Cartesian3.ZERO, // 无平移
          hpr, // 旋转
          new Cesium.Cartesian3(1.0, 1.0, 1.0) // 无缩放
        );

        return Cesium.Matrix4.fromTranslationRotationScale(
          translationRotationScale
        );
      }

      this.particleSystem = particleSystem;
      this.preUpdateEvent();
    },
    //场景渲染事件
    preUpdateEvent() {
      let _this = this;
      viewer.scene.preUpdate.addEventListener(function (scene, time) {
        //发射器地理位置
        _this.particleSystem.modelMatrix = _this.computeModelMatrix(
          _this.entity,
          time
        );
        //发射器局部位置
        _this.particleSystem.emitterModelMatrix =
          _this.computeEmitterModelMatrix();
        // 将发射器旋转
        if (_this.viewModel.spin) {
          _this.viewModel.heading += 1.0;
          _this.viewModel.pitch += 1.0;
          _this.viewModel.roll += 1.0;
        }
      });
    },
    applyGravity(p, dt) {
      var gravityScratch = new Cesium.Cartesian3();
      var position = p.position;
      Cesium.Cartesian3.normalize(position, gravityScratch);
      Cesium.Cartesian3.fromElements(
        20 * dt,
        gravityScratch.y * dt,
        -30 * dt,
        gravityScratch
      );
      p.velocity = Cesium.Cartesian3.add(
        p.velocity,
        gravityScratch,
        p.velocity
      );
    },
    computeModelMatrix(entity, time) {
      return entity.computeModelMatrix(time, new Cesium.Matrix4());
    },
    computeEmitterModelMatrix() {
      this.hpr = Cesium.HeadingPitchRoll.fromDegrees(0.0, 0.0, 0.0, this.hpr);
      this.trs.translation = Cesium.Cartesian3.fromElements(
        -4.0,
        0.0,
        1.4,
        this.translation
      );
      this.trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(
        this.hpr,
        this.rotation
      );

      return Cesium.Matrix4.fromTranslationRotationScale(
        this.trs,
        this.emitterModelMatrix
      );
    },

    // 初始化场景函数
    async initializeScene() {
      this.resetSimulation();

      // 设置场景位置（示例坐标，实际使用时替换为你的坐标）
      const center = Cesium.Cartesian3.fromDegrees(116.4, 39.9, 500);

      // 创建水库水体（使用多边形填充）
      this.reservoir = viewer.entities.add({
        name: "水库",
        polygon: {
          hierarchy: createReservoirShape(center),
          material: new Cesium.ColorMaterialProperty(
            Cesium.Color.BLUE.withAlpha(0.6)
          ),
          extrudedHeight: new Cesium.CallbackProperty(function () {
            return this.waterLevel;
          }, false),
          height: 0,
          outline: true,
          outlineColor: Cesium.Color.BLUE,
          outlineWidth: 2,
        },
      });

      // 加载泄洪道3DTiles模型（替换为你的实际资产ID）
      this.spillwayTileset = viewer.scene.primitives.add(
        new Cesium.Cesium3DTileset({
          url: Cesium.IonResource.fromAssetId(1234567), // 示例ID，需要替换
          dynamicScreenSpaceError: true,
          maximumScreenSpaceError: 2,
        })
      );

      // 创建闸门（简化为矩形实体）
      this.createGates(center);

      // 定位到场景
      viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(116.4, 39.9, 1500),
        orientation: {
          heading: Cesium.Math.toRadians(0),
          pitch: Cesium.Math.toRadians(-30),
          roll: 0.0,
        },
      });
    },
    // 创建闸门
    createGates(center) {
      // 清除现有闸门
      this.gateEntities.forEach((entity) => viewer.entities.remove(entity));
      this.gateEntities = [];

      // 创建3个闸门（简化为矩形）
      const gateCount = 3;
      const gateWidth = 20;
      const gateSpacing = 30;
      const totalWidth = gateCount * gateWidth + (gateCount - 1) * gateSpacing;
      for (let i = 0; i < gateCount; i++) {
        const gatePosition = Cesium.Cartesian3.fromElements(
          center.x -
            totalWidth / 2 +
            i * (gateWidth + gateSpacing) +
            gateWidth / 2,
          center.y + 100, // 水库边缘位置
          center.z
        );
        const gateEntity = viewer.entities.add({
          name: `闸门 ${i + 1}`,
          position: gatePosition,
          box: {
            dimensions: new Cesium.Cartesian3(gateWidth, 5, 40),
            material: Cesium.Color.GRAY,
            outline: true,
            outlineColor: Cesium.Color.BLACK,
          },
          orientation: Cesium.Quaternion.fromHeadingPitchRoll(
            Cesium.Math.toRadians(90),
            0,
            0
          ),
        });
        this.gateEntities.push(gateEntity);
      }
    },

    // 更新闸门位置（模拟开启）
    updateGatePosition(opennessPercent) {
      const openness = opennessPercent / 100;

      this.gateEntities.forEach((gate) => {
        const position = gate.position.getValue();
        const newPosition = Cesium.Cartesian3.fromElements(
          position.x,
          position.y,
          this.waterLevel - 40 * openness // 闸门下降高度
        );
        gate.position = newPosition;
      });
    },

    // 自动开启闸门动画
    autoOpenGate() {
      this.isGateOpening = true;
      const duration = 5000; // 动画持续时间(毫秒)
      const startTime = Date.now();

      function animate() {
        const elapsed = Date.now() - startTime;
        const progress = Math.min(elapsed / duration, 1);
        this.currentGateOpenness = Math.round(progress * 100);

        document.getElementById("gateOpenness").value =
          this.currentGateOpenness;
        document.getElementById("gateOpennessValue").textContent =
          this.currentGateOpenness;
        this.updateGatePosition(this.currentGateOpenness);
        this.updateSimulationParameters();

        if (progress < 1) {
          requestAnimationFrame(animate);
        } else {
          this.isGateOpening = false;
        }
      }

      animate();
    },

    // 更新模拟参数
    updateSimulationParameters() {
      // 根据闸门开度调整流量
      this.simulationParams.flowRate = 50 * (this.currentGateOpenness / 100);
      document.getElementById("flowRate").value =
        this.simulationParams.flowRate;
      document.getElementById("flowRateValue").textContent =
        this.simulationParams.flowRate;

      // 如果闸门开启且没有水流，则创建水流
      if (this.currentGateOpenness > 0 && !this.particleSystem) {
        this.createWaterFlow();
      }

      // 更新粒子系统
      if (this.particleSystem) {
        this.updateParticleSystem();
      }
    },

    // 创建水流效果
    createWaterFlow() {
      // 获取闸门位置作为起点
      const firstGate = this.gateEntities[0];
      const startPosition = firstGate.position.getValue();

      // 创建泄洪路径（简化为直线，实际应沿泄洪道模型）
      const pathPoints = [];
      const steps = 20;
      const pathLength = 1000; // 泄洪道长度(米)

      for (let i = 0; i <= steps; i++) {
        const ratio = i / steps;
        const x = startPosition.x + pathLength * ratio;
        const y = startPosition.y - 50 * ratio; // 稍微向左偏转
        const z = startPosition.z - 100 * ratio * ratio; // 抛物线下降

        pathPoints.push(new Cesium.Cartesian3(x, y, z));
      }

      // 创建粒子系统
      this.particleSystem = viewer.scene.primitives.add(
        new Cesium.ParticleSystem({
          image: createWaterTexture(),
          startColor: Cesium.Color.AQUA.withAlpha(0.9),
          endColor: Cesium.Color.AQUA.withAlpha(0.0),
          startScale: 1.0,
          endScale: 2.5,
          minimumParticleLife: 1.0,
          maximumParticleLife: 3.0,
          minimumSpeed: this.simulationParams.flowSpeed * 0.8,
          maximumSpeed: this.simulationParams.flowSpeed * 1.2,
          imageSize: new Cesium.Cartesian2(25, 25),
          emissionRate: this.simulationParams.flowRate,
          lifetime: 16.0,
          emitter: new Cesium.CircleEmitter(2.0),
          modelMatrix: Cesium.Matrix4.IDENTITY,
          emitterModelMatrix: Cesium.Matrix4.IDENTITY,
          forces: [applyWaterFlowForce],
        })
      );

      // 动画移动粒子发射器
      let currentIndex = 0;
      this.animationInterval = setInterval(() => {
        // 更新水位（闸门开启时才下降）
        if (this.currentGateOpenness > 0) {
          this.waterLevel = Math.max(
            0,
            this.waterLevel - this.simulationParams.waterDecreaseRate
          );
        }

        // 移动发射器
        currentIndex = (currentIndex + 1) % pathPoints.length;
        const position = pathPoints[currentIndex];

        // 计算模型矩阵
        const translation = Cesium.Matrix4.fromTranslation(
          position,
          new Cesium.Matrix4()
        );
        const rotation = Cesium.Matrix3.fromRotationX(
          Cesium.Math.toRadians(-90),
          new Cesium.Matrix3()
        );
        const rotationMatrix = Cesium.Matrix4.fromRotationTranslation(rotation);
        this.particleSystem.modelMatrix = Cesium.Matrix4.multiply(
          translation,
          rotationMatrix,
          new Cesium.Matrix4()
        );

        // 如果回到起点，检查水位
        if (currentIndex === 0 && this.waterLevel <= 0) {
          this.stopWaterFlow();
        }
      }, 100);
    },

    // 更新粒子系统参数
    updateParticleSystem() {
      if (this.particleSystem) {
        this.particleSystem.emissionRate = this.simulationParams.flowRate;
        this.particleSystem.minimumSpeed =
          this.simulationParams.flowSpeed * 0.8;
        this.particleSystem.maximumSpeed =
          this.simulationParams.flowSpeed * 1.2;
      }
    },

    // 自定义力函数（水流物理）
    applyWaterFlowForce(particle, dt) {
      // 主要向下流动
      particle.velocity.z -= 9.8 * dt * 0.5;

      // 向前流动（沿泄洪道方向）
      particle.velocity.x += 2.0 * dt;

      // 添加一些随机性使效果更自然
      particle.velocity.x += (Math.random() - 0.5) * 0.5;
      particle.velocity.y += (Math.random() - 0.5) * 0.3;

      // 根据粒子生命周期调整大小
      const lifeRatio = particle.life / particle.maximumLife;
      particle.size = 1.0 + 1.5 * lifeRatio;
    },

    // 创建水纹理
    createWaterTexture() {
      const canvas = document.createElement("canvas");
      canvas.width = 30;
      canvas.height = 30;
      const context = canvas.getContext("2d");

      // 绘制圆形渐变作为水粒子
      const centerX = canvas.width / 2;
      const centerY = canvas.height / 2;
      const gradient = context.createRadialGradient(
        centerX,
        centerY,
        0,
        centerX,
        centerY,
        centerX
      );
      gradient.addColorStop(0, "rgba(150, 220, 255, 0.9)");
      gradient.addColorStop(1, "rgba(100, 180, 255, 0.1)");

      context.fillStyle = gradient;
      context.beginPath();
      context.arc(centerX, centerY, centerX, 0, Math.PI * 2, true);
      context.fill();

      return canvas;
    },

    // 停止水流
    stopWaterFlow() {
      if (this.particleSystem) {
        viewer.scene.primitives.remove(this.particleSystem);
        this.particleSystem = null;
      }
      if (this.animationInterval) {
        clearInterval(this.animationInterval);
        this.animationInterval = null;
      }
    },

    // 重置模拟
    resetSimulation() {
      // 清除现有实体
      if (this.reservoir) viewer.entities.remove(this.reservoir);
      this.gateEntities.forEach((entity) => viewer.entities.remove(entity));
      this.gateEntities = [];
      this.stopWaterFlow();

      // 重置参数
      this.waterLevel = 100;
      this.currentGateOpenness = 0;
      this.isGateOpening = false;
      this.simulationParams.flowSpeed = 3;
      this.simulationParams.flowRate = 50;

      // 重置UI
      document.getElementById("gateOpenness").value = 0;
      document.getElementById("gateOpennessValue").textContent = "0";
      document.getElementById("flowSpeed").value = 3;
      document.getElementById("flowSpeedValue").textContent = "3";
      document.getElementById("flowRate").value = 50;
      document.getElementById("flowRateValue").textContent = "50";
    },
  },
};
</script>


<style lang="scss">
#cesiumContainer {
  position: absolute;
  width: 100%;
  height: 100vh;
  top: 0px;
  left: 0px;
  overflow: hidden;
}
#toolbar {
  position: absolute;
  top: 100px;
  left: 10px;
  background: rgba(42, 42, 42, 0.8);
  padding: 10px;
  border-radius: 5px;
  z-index: 999;
  button {
    padding: 5px 10px;
    margin: 2px;
    cursor: pointer;
  }
}

#controlPanel {
  position: absolute;
  top: 50px;
  left: 10px;
  background: rgba(42, 42, 42, 0.8);
  padding: 10px;
  border-radius: 5px;
  z-index: 999;
  color: white;
  width: 250px;

  .control-group {
    margin-bottom: 10px;
  }
  button,
  input[type="range"] {
    width: 100%;
    margin: 5px 0;
  }
  .slider-container {
    display: flex;
    align-items: center;
  }
  .slider-value {
    margin-left: 10px;
    min-width: 30px;
    text-align: right;
  }
}
</style>
